"""
用户相关的Pydantic模式
"""

from pydantic import BaseModel, EmailStr, Field, validator
from typing import Optional
from datetime import datetime


class UserBase(BaseModel):
    """用户基础模式"""
    email: EmailStr = Field(..., description="邮箱地址")
    nickname: Optional[str] = Field(None, max_length=100, description="用户昵称")


class UserCreate(UserBase):
    """用户创建模式"""
    password: str = Field(..., min_length=8, max_length=20, description="密码")
    confirm_password: str = Field(..., description="确认密码")
    
    @validator('confirm_password')
    def passwords_match(cls, v, values):
        if 'password' in values and v != values['password']:
            raise ValueError('两次输入的密码不一致')
        return v
    
    @validator('password')
    def validate_password(cls, v):
        if not any(c.isalpha() for c in v):
            raise ValueError('密码必须包含字母')
        if not any(c.isdigit() for c in v):
            raise ValueError('密码必须包含数字')
        return v


class UserLogin(BaseModel):
    """用户登录模式"""
    email: EmailStr = Field(..., description="邮箱地址")
    password: str = Field(..., description="密码")


class UserUpdate(BaseModel):
    """用户更新模式"""
    nickname: Optional[str] = Field(None, max_length=100, description="用户昵称")
    avatar_url: Optional[str] = Field(None, max_length=500, description="头像URL")
    notification_email: Optional[bool] = Field(None, description="是否接收邮件通知")
    notification_wechat: Optional[bool] = Field(None, description="是否接收微信通知")
    timezone: Optional[str] = Field(None, max_length=50, description="用户时区")


class UserResponse(UserBase):
    """用户响应模式"""
    id: int = Field(..., description="用户ID")
    nickname: Optional[str] = Field(None, description="用户昵称")
    avatar_url: Optional[str] = Field(None, description="头像URL")
    is_active: bool = Field(..., description="是否激活")
    is_verified: bool = Field(..., description="邮箱是否验证")
    notification_email: bool = Field(..., description="是否接收邮件通知")
    notification_wechat: bool = Field(..., description="是否接收微信通知")
    timezone: str = Field(..., description="用户时区")
    created_at: datetime = Field(..., description="创建时间")
    last_login_at: Optional[datetime] = Field(None, description="最后登录时间")
    
    # 扩展信息
    current_balance: float = Field(..., description="当前余额")
    active_monitors_count: int = Field(..., description="活跃监控数量")
    
    class Config:
        from_attributes = True


class Token(BaseModel):
    """JWT令牌模式"""
    access_token: str = Field(..., description="访问令牌")
    token_type: str = Field(default="bearer", description="令牌类型")
    expires_in: int = Field(..., description="过期时间（秒）")
    user: UserResponse = Field(..., description="用户信息")


class TokenData(BaseModel):
    """令牌数据模式"""
    user_id: Optional[int] = None
    email: Optional[str] = None


class EmailVerification(BaseModel):
    """邮箱验证模式"""
    email: EmailStr = Field(..., description="邮箱地址")
    verification_code: str = Field(..., min_length=6, max_length=6, description="验证码")


class PasswordReset(BaseModel):
    """密码重置模式"""
    email: EmailStr = Field(..., description="邮箱地址")
    reset_token: str = Field(..., description="重置令牌")
    new_password: str = Field(..., min_length=8, max_length=20, description="新密码")
    confirm_password: str = Field(..., description="确认新密码")
    
    @validator('confirm_password')
    def passwords_match(cls, v, values):
        if 'new_password' in values and v != values['new_password']:
            raise ValueError('两次输入的密码不一致')
        return v


class PasswordChange(BaseModel):
    """密码修改模式"""
    current_password: str = Field(..., description="当前密码")
    new_password: str = Field(..., min_length=8, max_length=20, description="新密码")
    confirm_password: str = Field(..., description="确认新密码")
    
    @validator('confirm_password')
    def passwords_match(cls, v, values):
        if 'new_password' in values and v != values['new_password']:
            raise ValueError('两次输入的密码不一致')
        return v
